﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Channels;
using System.Text;
using System.Threading.Tasks;

namespace WJP.DataPortal.Helper
{
    internal class CompactMessageEncodingBindingElement : MessageEncodingBindingElement
    {
        /// <summary>Stores the inner binding element</summary>
        private MessageEncodingBindingElement _innerBindingElement;

        /// <summary>Stores the base binding element so clones can use it.</summary>
        private CompactMessageEncodingBindingElement _baseBindingElement;

        /// <summary>Returns the inner binding element</summary>
        internal MessageEncodingBindingElement InnerBindingElement
        {
            get
            {
                return this._innerBindingElement;
            }
            set
            {
                this._innerBindingElement = value;
            }
        }

        /// <summary>Get/Set the message version</summary>
        public override MessageVersion MessageVersion
        {
            get
            {
                return this._innerBindingElement.MessageVersion;
            }
            set
            {
                this._innerBindingElement.MessageVersion = value;
            }
        }

        /// <summary>
        /// Builds the channel factory stack on the client that creates a specified type of channel for a specified context.
        /// </summary>
        public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
        {
            context.BindingParameters.Add((object)this);
            return base.BuildChannelFactory<TChannel>(context);
        }

        /// <summary>
        /// Builds the channel listener on the service that accepts a specified type of channel for a specified context.
        /// </summary>
        public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
        {
            context.BindingParameters.Add((object)this);
            return base.BuildChannelListener<TChannel>(context);
        }

        /// <summary>Create the CompactMessageEncoderFactory</summary>
        /// <returns></returns>
        public override MessageEncoderFactory CreateMessageEncoderFactory()
        {
            return (MessageEncoderFactory)new CompactMessageEncoderFactory(this._innerBindingElement.CreateMessageEncoderFactory());
        }

        /// <summary>
        /// Returns a typed object requested, if present, from the appropriate layer in the binding element stack.
        /// </summary>
        public override T GetProperty<T>(BindingContext context)
        {
            T obj = this._innerBindingElement.GetProperty<T>(context);
            if ((object)obj == null)
                obj = context.GetInnerProperty<T>();
            return obj;
        }

        /// <summary>Clone the CompactMessageEncodingBindingElement</summary>
        /// <returns></returns>
        public override BindingElement Clone()
        {
            return (BindingElement)new CompactMessageEncodingBindingElement(this);
        }

        /// <summary>Constructor, used with the Clone method</summary>
        /// <param name="originalBindingElement"></param>
        private CompactMessageEncodingBindingElement(CompactMessageEncodingBindingElement originalBindingElement)
        {
            this._innerBindingElement = originalBindingElement._innerBindingElement;
            if (originalBindingElement._baseBindingElement == null)
                this._baseBindingElement = originalBindingElement;
            else
                this._baseBindingElement = originalBindingElement._baseBindingElement;
        }

        internal CompactMessageEncodingBindingElement()
        {
        }
    }
}
